package com.forum.service.impl;

import cn.undraw.util.result.R;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.forum.common.LoginUtil;
import com.forum.dao.CommentDao;
import com.forum.dao.LikesDao;
import com.forum.dao.NoteDao;
import com.forum.dao.UserDao;
import com.forum.dto.NoteDTO;
import com.forum.entity.*;
import com.forum.service.NoteService;
import com.forum.vo.NoteVO;
import com.forum.vo.UserLccVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
@Slf4j
public class NoteServiceImpl implements NoteService {

    @Resource
    UserDao userDao;
    @Resource
    private NoteDao noteDao;
    @Resource
    private LikesDao likesDao;

    @Resource
    private CommentDao commentDao;

    @Resource
    private UserServiceImpl userServiceImpl;

    //添加文章
    @Override
    public Result1 addNote(NoteDTO noteDTO) {
        System.out.println("getUserId:" + LoginUtil.getCurrentId());
        //判断用户是否存在
        int haveId = noteDao.checkIdHave(LoginUtil.getCurrentId());  //获取用户上下文
//        int haveId = noteDao.checkIdHave(noteDTO.getUserId());  //获取用户上下文
        System.out.println(haveId == 0);
        //判断文章类型输入是否正确

        if (noteDTO.getType() < 0 || noteDTO.getType() > 4) {
            System.out.println("类型不在范围之内");
            return Result1.error("类型不在范围之内");
        } else if (haveId == 0) {
            System.out.println("没有该用户Id,添加失败");
            return Result1.error("没有该用户Id,添加失败");
        }

        //配置实体类各个数据
        noteDTO.setUserId(LoginUtil.getCurrentId());  //把当前用户id给添加文章接口使用
        noteDTO.setCreateTime(LocalDateTime.now());
        noteDTO.setUpdateTime(LocalDateTime.now());
        String imglist = JSONObject.toJSONString(noteDTO.getImg());  //把图片数组转成字符串
        String filelist = JSONObject.toJSONString(noteDTO.getAnnex());  //把文件数组转成字符串

        //把配置好的数据，给实体类，然后存储到数据表中
        Note note = new Note();
        note.setUserId(noteDTO.getUserId());
        note.setTitle(noteDTO.getTitle());
        note.setMsg(noteDTO.getMsg());
        note.setImg(imglist);  //把图片字符串给实体类note
        note.setAnnex(filelist);  //把文件字符串给实体类note
        note.setType(noteDTO.getType());
        note.setOutline(noteDTO.getOutline());
        note.setCreateTime(noteDTO.getCreateTime());
        note.setUpdateTime(noteDTO.getUpdateTime());

        System.out.println("要添加的文章:" + note);

        noteDao.addNote(note);
        return Result1.success("添加成功");
    }

    //查询文章，可根据用户id，文章类型查询
    @Override
    public List<NoteVO> findNote(Integer id, Integer userId, Integer type, LocalDateTime updateTime, String noteTitle, int page, int pageSize,int orderByLike) {

        //从缓存拿取数据
//        String noteCacheKey = "note:list";
//        String cache = (String) redisTemplate.opsForValue().get(noteCacheKey);
//        if (StrUtil.isNotBlank(cache)) {
//            List<NoteVO> noteVOS = JSONUtil.toList(cache, NoteVO.class);
//            return noteVOS;
//        }

        //根据条件查询文章表，返回Note集合
        List<Note> notes = noteDao.findNote(id, userId, type, noteTitle, updateTime);
        if (notes == null || notes.size() == 0) {
            return null;
        }



        //创建NoteVO集合，用于把处理完成的数据返回给前端
        List<NoteVO> noteVOS = new ArrayList<>();

        // 开始时间
        long stime = System.currentTimeMillis();
        notes.forEach(item -> {
            //循环查询到的note集合，把不用处理的数据插入到vo集合中
            NoteVO noteVO = new NoteVO();
            noteVO.setId(item.getId());
            noteVO.setTitle(item.getTitle());
            noteVO.setMsg(item.getMsg());
            noteVO.setUserId(item.getUserId());
            noteVO.setOutline(item.getOutline());
            noteVO.setType(item.getType());
            noteVO.setCreateTime(item.getCreateTime());
            noteVO.setUpdateTime(item.getUpdateTime());
            noteVO.setAuthorInfo(userServiceImpl.findUserByNoteId(item.getId())); //作者详情

            //处理图片和文件字段，把JSON字符串转成String集合返回
            if (item.getImg() != null) {
                noteVO.setImg(JSON.parseArray(item.getImg(), String.class));
            }
            if (item.getAnnex() != null) {
                noteVO.setAnnex(JSON.parseArray(item.getAnnex(), String.class));
            }

            //获取文章点赞数和收藏数
            noteVO.setLikeCount(likesDao.getLikes(item.getId(), 1));//给集合的点赞数赋值
            noteVO.setCollectionCount(likesDao.getCollections(item.getId(), 1));//给集合的收藏数赋值


            noteVOS.add(noteVO);
        });

        //简单排序  按照点赞数从高到低排序
        if(orderByLike == 1){
            for (int i = 0; i < noteVOS.size() - 1; i++) {
                for (int j = i + 1; j < noteVOS.size(); j++) {
                    if (noteVOS.get(i).getLikeCount() < noteVOS.get(j).getLikeCount()) {
                        Collections.swap(noteVOS, i, j);
                    }
                }
            }
        }

        // 结束时间
        long etime = System.currentTimeMillis();

        // 计算执行时间
        System.out.printf("执行时长：%d 毫秒.", (etime - stime));

        //把数据存入缓存
//        redisTemplate.opsForValue().set(noteCacheKey,JSONUtil.toJsonStr(noteVOS));

        //设置分页
        Integer count = noteVOS.size();  //记录总数
        Integer pageCount = 0;      //记录页数
        if (count % pageSize == 0) {
            pageCount = count / pageSize;
        } else {
            pageCount = count / pageSize + 1;
        }
        int firstIndex = 0;  //切割集合的起始索引
        int lastIndex = 0;      //切割集合的结束索引
        if (page > pageCount) {  //表示到最后一页了
            page = pageCount;
        }
        if (page != pageCount) {
            firstIndex = (page - 1) * pageSize;
            lastIndex = firstIndex + pageSize;
        } else {
            firstIndex = (page - 1) * pageSize;
            lastIndex = count;
        }

        return noteVOS.subList(firstIndex, lastIndex);
    }

    //更新文章
    @Override
    public Result1 update(NoteDTO noteDTO) {
        //判断用户是否存在
        int haveId = noteDao.checkIdHave(LoginUtil.getCurrentId());  //获取用户上下文

//        //判断文章类型输入是否正确
        if (noteDTO.getType() != null) {
            if (noteDTO.getType() < 0 || noteDTO.getType() > 2) {
                return Result1.error("类型不在范围之内");
            }
        }
        if (haveId == 0) {
            return Result1.error("没有该用户Id,添加失败");
        }

        //配置实体类各个数据
        noteDTO.setUpdateTime(LocalDateTime.now());  //更新修改时间
        String imglist = null;
        String filelist = null;
        if (noteDTO.getImg() != null) {
            imglist = JSONObject.toJSONString(noteDTO.getImg());  //把图片数组转成字符串
        }
        if (noteDTO.getAnnex() != null) {
            filelist = JSONObject.toJSONString(noteDTO.getAnnex());  //把文件数组转成字符串
        }

        //把配置好的数据，给实体类，然后存储到数据表中
        Note note = new Note();
        note.setId(noteDTO.getId());
        note.setTitle(noteDTO.getTitle());
        note.setMsg(noteDTO.getMsg());
        note.setType(noteDTO.getType());
        note.setUpdateTime(noteDTO.getUpdateTime());
        note.setImg(imglist);  //把图片字符串给实体类note
        note.setAnnex(filelist);  //把文件字符串给实体类note
        note.setOutline(noteDTO.getOutline());
        log.info("处理完成，真实需要修改的数据：{}", note);

        noteDao.update(note);
        return Result1.success("修改成功");
    }

    //删除文章
    @Override
    public Result1 delNote(Integer id) {
        noteDao.delNote(id);
        return Result1.success("删除成功");
    }

    @Override
    public Integer findNoteByUserId(Integer noteId) {
        return noteDao.findNoteByUserId(noteId);
    }

    @Override
    public int getNoteNumByUserId(Integer userId) {
        int num = noteDao.getNoteNumByUserId(userId);
        return num;
    }

    @Override
    public R seleUserByLCC(Integer noteId) {
        Integer userId = LoginUtil.getCurrentId();
        Likes likesList = new Likes();
        likesList.setUserId(userId);
        likesList.setNoteId(noteId);

        UserLccVO userLccVO = new UserLccVO();//初始化VO类

        //查点赞 todo:判断为空时的处理方式参考
        List<Likes> likes = likesDao.queryByLike(likesList);
        Integer likeActive;
        if (likes != null && !likes.isEmpty()) {
            likeActive = likes.get(0).getActive();
        } else {
            likeActive = 0;
        }

        //查收藏
//        List<Collection> collections = likesDao.queryByCondition(likesList);
        Collection collections = likesDao.queryByarticleId(noteId, userId);
        Integer active;
        if (collections != null) {
            active = collections.getActive();
        } else {
            active = 0;
        }

        //查关注
        //通过文章id与用户id是否在关注表里
        int count;
        if (likes != null && !likes.isEmpty()) {
            Integer noteUserId = likesDao.queryByNote(likesList);

            Concern concern = new Concern();
            concern.setGzId(LoginUtil.getCurrentId());
            concern.setBgzId(noteUserId);

            List<Concern> concerns = likesDao.selectConcern(concern);
            if (!CollectionUtils.isEmpty(concerns)) {  //判断size是否为0 //size为0
                count = 0;
                userLccVO.setConcernActive(count);
            } else {
                count = 1;
                userLccVO.setConcernActive(count);
            }
        } else {
            count = 1;
            userLccVO.setConcernActive(count);
        }

        //获取评论数
        Integer commentCount = commentDao.count(noteId);

        //将得到的数据插入vo
        userLccVO.setUserId(LoginUtil.getCurrentId());
        userLccVO.setNoteId(noteId);
        userLccVO.setLikeActive(likeActive);
        userLccVO.setCollectionActive(active);
        userLccVO.setCommentCount(commentCount);
        //拼接，返回VO层
//        List<UserLccVO> userLccVOList = noteDao.seleUserByLCC(noteId);
        return R.ok(userLccVO);
    }
}
